<style lang=less scoped>
	@import "../../variables.less";
	@import "../../resource/common.less";

	@currentWidth: 650px;
	@attachWidth: 150px;
	.eleUse {
		width: 33%;
		height: 80px;
		display: flex;
		justify-content: center;
		align-items: center;
		flex-direction: column;

		&:nth-child(2) {
			&:before {
				content: "";
				width: 1px;
				border-left: 1px solid #FFF;
				height: 80%;
				top: 10%;
				left: 0;
				position: absolute;
				display: block;
			}

			&:after {
				content: "";
				width: 1px;
				border-right: 1px solid #FFF;
				height: 80%;
				top: 10%;
				right: 0;
				position: absolute;
				display: block;
			}
		}
	}

	.eleType {
		width: 25%;
		border: 1px solid lighten(@lightTitleBackground, 30%);
		margin: @smallSpace;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		height: 80px;
		cursor: pointer;

		&.active {
			filter: drop-shadow(2px 4px 6px black)
		}

		> :first-child {
			margin: @smallSpace 0;
		}
	}

	.row {
		width: 100%;
		height: 80px;
		display: flex;
		flex-direction: row;
		margin-bottom: @bigSpace;

		&:last-child {
			flex-grow: 1;
		}
	}

	.eleTypeUsed {
		display: block;
		width: 100%;

		> div:first-child {
			width: 60%;
			float: left;
			text-align: right;
			padding-right: @smallSpace;
		}

		> div:last-child {
			width: 40%;
			margin-left: 60%;
			text-align: left;
			border-left: 1px solid #EEE;
			padding-left: @smallSpace;
		}
	}

	.circleList {
		width: 46%;
		height: 100%;
		display: flex;
		flex-direction: column;
		margin: 0 2%;

		> div:last-child {
			flex-grow: 1;
		}
	}
</style>
<template>
	<div class="mainContent">
		<div class="head">
			耗电总览
		</div>
		<div class="row">
			<div class="eleUse">
				今日用电量
				<br>
				<div>
					<count-up :end=todayUsed :start=0 style="font-size: 20px" />
					kW·h
				</div>
			</div>
			<div class="eleUse">
				<div>
					所选时间用电量
					<span :style="selectedUse.change|toPercent(selectedUse.count)|toBackgroundColor"
						style="display: inline-block;width: 50px;border-radius: 5px;text-align: center;font-size: 12px">{{selectedUse.change|toPercent(selectedUse.count)}}</span>
				</div>
				<div>
					<count-up :end="selectedUse.count" :start=0 style="font-size: 20px" />
					kW·h
				</div>
			</div>
			<div class="eleUse">
				统计范围
				<br>
				<DatePicker :options="options" @on-change="getEleCount" size=small style="width: 200px" type="daterange"
					v-model="dateRange" />
			</div>
		</div>
		<div class="blockTitle">用电类别统计</div>
		<div class="row">
			<div :class="{active:activeFirst===i.id}" :key="i.id" @click="setActive(i.id)" class="eleType"
				v-for="i in system">
				<span>{{i.name}}</span>
				<div class="eleTypeUsed">
					<div>
						<count-up :end="i.count" :start="0" style="font-size: 16px" />
						<br>
						<span>kW·h</span>
					</div>
					<div>
						<span style="color: #888">变化</span>
						<br>
						<span :style="i.change|toPercent(i.count)|toBackgroundColor"
							style="display: inline-block;width: 50px;border-radius: 5px;text-align: center;font-size: 12px">{{i.change|toPercent(i.count)}}</span>
					</div>
				</div>
			</div>
		</div>
		<div class="blockTitle">{{chartTitle}}分布</div>
		<div class="row" style="height: unset">
			<div :id="id" style="width: 45%;height: 300px;float: left"></div>
			<div style="width: 55%;height: 300px">
				<Loading style="position: absolute;top: 0;width: 100%" :height=300 v-if="lineLoading" />
				<div :id="id2" />
			</div>
		</div>
		<div class="blockTitle">
			{{chartTitle}}所属回路用电
			<Input prefix="ios-search" size=small style="float:right;width: 120px;margin-bottom: 4px;"
				v-model="keyword" />
		</div>
		<div class="row">
			<div class="circleList">
				<div style="margin-bottom: 4px;">回路用电排名</div>
				<div style="height: 100px;overflow: auto">
					<ul>
						<li :key="i.id" v-for="i in cirUse">
							<span
								style="width: 55%;display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">{{i.name}}</span>
							<span
								style="width: 15%;display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">{{i.count}}</span>
							<span
								style="width: 30%;display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
								<div :style="i.len"
									style="background-color: dodgerblue;height: 17px;margin: 2px 0;" />
							</span>
						</li>
					</ul>
				</div>
			</div>
			<div class="circleList" style="width: 50%">
				<div style="margin-bottom: 4px;">
					回路用电涨跌幅排名
					<Select size=small style="float: right;width: 100px" v-model="sortType">
						<Option :value="-1">涨幅排名</Option>
						<Option :value="1">跌幅排名</Option>
					</Select>
				</div>
				<div style="height: 100px;overflow: auto">
					<ul>
						<li :key="i.id" v-for="i in afterSort">
							<span
								style="width: 55%;display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">{{i.name}}</span>
							<span
								style="width: 15%;display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis" />
							<span
								:style="{backgroundColor: i.color}"
								style="width: 30%;display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;text-align: center;border-radius: 5px">
								{{i.changeString}}
							</span>
						</li>
					</ul>
				</div>
			</div>
		</div>
	</div>
</template>
<script lang=ts>
	import { Component, Vue, Watch } from "vue-property-decorator";
	import { DatePicker, Input, Option, Select } from "view-design";
	import CountUp from "@/components/countup/countup.vue";
	import request from "@/request";
	import moment from "moment";
	import G2 from "@antv/g2";
	import Loading from "@/components/loading/Loading.vue";
	import { Route } from "vue-router";

	interface EleLeaf {
		name:string,
		id:number,
		count:number,
		deep:number,
		children?:EleLeaf[],
		change?:number
	}

	@Component({
		components: {
			DatePicker,
			CountUp,
			Select,
			Option,
			Loading,
			Input
		},
		filters: {
			toPercent (change:number, total:number):string {
				if (total === 0) {
					return "- 0";
				} else {
					const percentage = change / (total - change) * 100;
					if (percentage > 0) {
						return "↑ " + percentage.toFixed(1) + "%";
					} else {
						return "↓ " + (-percentage.toFixed(1)) + "%";
					}
				}
			},
			toBackgroundColor (change:string):string {
				if (/↑/.test(change)) {
					return "background-color:#FF5C5C";
				} else {
					return "background-color:dodgerblue";
				}
			}
		}
	})
	export default class EnergyCount extends Vue {
		dateRange:Date[] = [ new Date(new Date().setDate(1)), new Date(Date.now() - 24 * 3600 * 1000) ];
		system:EleLeaf[] = [];
		sortType:1 | -1 = -1;
		activeFirst:number = 0;
		activeSecond:number = 0;
		lineLoading:boolean = true;
		todayUsed:number = 0;
		keyword:string = "";
		readonly options = {
			disabledDate (date:any):boolean {
				return Date.parse(date) > (Date.now() - 24 * 3600 * 1000);
			}
		};
		readonly id:string = "energyCountPie";
		readonly id2:string = "energyCountLine";
		private chart?:G2.Chart;
		private interval?:G2.Geom;
		private area?:G2.Chart;
		private MainLink:HTMLLinkElement = document.createElement("link");

		get cirUse () {
			let temp:{ id:number, name:string, len:string, change:number, count:number }[] = [];
			let max:number = 0;
			let temp2:EleLeaf[];
			if (this.activeFirst === 0) {
				temp2 = this.system;
			} else {
				// @ts-ignore
				temp2 = [ this.system.find(t => t.id === this.activeFirst) ];
			}
			temp2.forEach(t => {
				t.children && t.children.forEach(o => {
					(o.id === this.activeSecond || this.activeSecond === 0) && o.children && o.children.forEach(u => {
						if (this.keyword === "" || u.name.indexOf(this.keyword) > -1) {
							max = Math.max(max, u.count);
							temp.push({
								id: u.id,
								name: u.name,
								get len ():string {
									if (max === 0) {
										return "width:100%";
									} else {
										return `width:${ u.count / max * 100 }%`;
									}
								},
								change: u.change || 0,
								count: u.count
							});
						}
					});
				});
			});
			return temp.sort((m, n) => -m.count + n.count);
		}

		get afterSort () {
			let temp:{ id:number, name:string, changePercent:number, changeString:string, color:string }[] = [];
			let temp2:EleLeaf[];
			if (this.activeFirst === 0) {
				temp2 = this.system;
			} else {
				// @ts-ignore
				temp2 = [ this.system.find(t => t.id === this.activeFirst) ];
			}
			temp2.forEach(t => {
				t.children && t.children.forEach(o => {
					(o.id === this.activeSecond || this.activeSecond === 0) && o.children && o.children.forEach(u => {
						if (this.keyword === "" || u.name.indexOf(this.keyword) > -1) {
							temp.push({
								id: u.id,
								name: u.name,
								get changePercent ():number {
									if (!u.change || u.change === 0) {
										return 0;
									} else {
										const lastCount:number = u.count - u.change;
										if (lastCount === 0) {
											return 100;
										} else {
											return (u.change / lastCount * 100);
										}
									}
								},
								get changeString ():string {
									const changePercent = this.changePercent;
									if (changePercent > 0) {
										return "↑ " + changePercent.toFixed(2) + "%";
									} else if (changePercent === 0) {
										return "- " + changePercent.toFixed(2) + "%";
									} else {
										return "↓ " + (changePercent * -1).toFixed(2) + "%";
									}
								},
								get color ():string {
									return (u.change && u.change > 0) ? "#FF5C5C" : "dodgerblue";
								}
							});
						}
					});
				});
			});
			temp = temp.sort((m, n) => ((m.changePercent - n.changePercent) * this.sortType));
			return temp;
		}

		get chartTitle ():string {
			if (this.activeFirst === 0) {
				return "总能耗";
			} else if (this.activeSecond === 0) {
				return this.system.find(t => t.id === this.activeFirst)!.name || "";
			} else {
				return this.system.find(t => t.id === this.activeFirst)!.children!.find(t => t.id === this.activeSecond)!.name || "";
			}
		}

		get selectedUse () {
			let a:number = 0;
			let b:number = 0;
			this.system.forEach(t => {
				a += t.count;
				b += t.change || 0;
			});
			return { count: a, change: b };
		}

		setActive (id:number) {
			if (id === this.activeFirst) {
				this.renderPie();
				this.activeFirst = 0;
			} else {
				this.renderPie(id);
				this.activeFirst = id;
			}
			this.activeSecond = 0;
			this.renderLine();
			this.renderLine();
		}

		getEleCount () {
			this.activeFirst = 0;
			this.activeSecond = 0;
			this.lineLoading = true;
			// @ts-ignore
			this.area.hide();
			this.system.forEach(t => {
				t.children = [];
			});
			request({
				url: "/energy/rest/Circuit/tongji/",
				params: {
					start: moment(this.dateRange[ 0 ]).format("YYYY-MM-DD"),
					end: moment(this.dateRange[ 1 ]).format("YYYY-MM-DD"),
					ordering: "id"
				}
			}).then(({ data }) => {
				const chunk:any[] = data.data;
				chunk.forEach((t:{ id:number, name:string, categoryitem:any[] }) => {
					const system = this.system.find(d => d.id === t.id);
					if (system) {
						let count:number = 0;
						let change:number = 0;
						t.categoryitem.forEach(d => {
							let circleCount:number = 0;
							let circleChange:number = 0;
							let temp:EleLeaf = {
								name: d.name,
								id: d.id,
								count: 0,
								children: [],
								deep: 2
							};
							(d.cir.涨跌幅排名 as any[]).forEach(e => {
								const id = e.id;
								const temp2 = d.cir.回路用电排名.find((f:any) => f.id === id);
								const value:number = temp2 ? Number(temp2.value) : 0;
								circleCount += value;
								circleChange += e.value;
								const leaf:EleLeaf = {
									name: e.Circuit,
									id: e.id,
									change: e.value,
									count: value,
									deep: 3
								};
								temp.children ? temp.children.push(leaf) : void 0;
							});
							count += circleCount;
							change += circleChange;
							temp.count = circleCount;
							temp.change = circleChange;
							system.children && system.children.push(temp);
						});
						system.count = count;
						system.change = change;
					}
				});
				this.renderPie();
				this.renderLine();
			});
		}

		renderPie (type:number | void) {
			let data;
			let total:number = 0;
			// @ts-ignore;
			this.chart!.hide();
			if (!type) {
				data = this.system.map(t => {
					total += t.count;
					return {
						item: t.name,
						count: t.count,
						id: t.id,
						deep: t.deep
					};
				});
			} else {
				// @ts-ignore
				data = this.system.find(s => s.id === type).children.map(t => {
					total += t.count;
					return {
						item: t.name,
						count: t.count,
						id: t.id,
						deep: t.deep
					};
				});
			}
			if (this.chart && this.interval) {
				this.chart.source(data, {
					count: {
						formatter: (val:number):string => {
							return (val / total * 100).toFixed(2) + "%";
						}
					}
				});
				this.interval.label("count", {
					offset: 0,
					formatter: (val:string, item:any):string => {
						return parseFloat(val) < 15 ? "" : item.point.item;
					},
					textStyle: {
						fill: "#FFF",
						fontSize: 12,
						textAlign: "center"
					},
					autoRotate: true
				});
				// @ts-ignore
				this.chart.show();
				this.chart.repaint();
			}
		}

		renderLine () {
			this.lineLoading = true;
			// @ts-ignore
			this.area.hide();
			let dataView:{ type:string, time:string, value:number }[] = [];
			let workLine:Promise<any>[] = [];
			let key:string = "";
			let valueChunk:EleLeaf[];
			// eslint-disable-next-line camelcase
			const time__range = [ moment(this.dateRange[ 0 ]).format("YYYY-MM-DDT00:00:00"), moment(this.dateRange[ 1 ]).format("YYYY-MM-DDT23:59:59") ].join();
			if (this.activeFirst === 0) {
				valueChunk = this.system;
				key = "EnergyCategory";
			} else if (this.activeSecond === 0) {
				valueChunk = this.system.find(t => t.id === this.activeFirst)!.children || [];
				key = "CategoryItem";
			} else {
				valueChunk = this.system.find(t => t.id === this.activeFirst)!.children!.find(t => t.id === this.activeSecond)!.children || [];
				key = "Circuit";
			}
			valueChunk.forEach(t => {
				workLine.push(
					request({
						url: "/energy/rest/MnitorData/",
						params: {
							time__range,
							[ key ]: t.id,
							type: "day",
							pagesize: 200
						}
					}).then(({ data }) => {
						if (data.results.length > 0) {
							const temp2:string = data.results[ 0 ].name;
							const type:string = t.deep === 2 ? (temp2 === "备用" ? ("备用" + t.id) : temp2) : temp2;
							data.results.forEach((j:any) => {
								dataView.push({
									type,
									value: j.D_value,
									time: j.time
								});
							});
						}
					})
				);
			});
			Promise.all(workLine).then(() => {
				this.area!.source(dataView, {
					value: {
						formatter (value:string):string {
							return parseFloat(value) + "kW·h";
						},
						tickCount: 5,
						type: "linear"
					},
					time: {
						type: "timeCat",
						range: [ 0, 1 ]
					}
				});
				this.area!.repaint();
				this.lineLoading = false;
				// @ts-ignore
				this.area.show();
			});
		}

		renderCss () {
			less.render(lessFiles.energyCount, {
				javascriptEnabled: true,
				modifyVars: {
					"@baseColor": this.$store.state.baseColor,
					"path": "/static/UnityWeb/desktop/"
				},
				paths: [ "/static/UnityWeb/desktop/" ]
			}).then(data => {
				this.MainLink && this.MainLink.remove();
				const href:string = URL.createObjectURL(new Blob([ data.css ]));
				const link = document.createElement("link");
				link.href = href;
				link.rel = "stylesheet";
				document.head.appendChild(link);
				this.MainLink = link;
			});
		}

		mounted ():void {
			this.renderCss();
			const data:any[] = [];
			const chart = new G2.Chart({
				container: this.id,
				forceFit: true,
				animate: false,
				height: 300
			});
			chart.source(data);
			chart.coord("theta", {
				radius: 1,
				innerRadius: 0.6
			});
			chart.tooltip({
				showTitle: false,
				itemTpl: "<li><span style=\"background-color:{color};\" class=\"g2-tooltip-marker\"></span>{name}: {value}kW·h</li>"
			});
			chart.guide().html({
				position: [ "50%", "50%" ],
				html: "<div style=\"color:#FFF;font-size: 14px;text-align: center;width: 10em;\">能耗比例</div>",
				alignX: "middle",
				alignY: "middle"
			});
			chart.legend("item", {
				textStyle: {
					fill: "#FFF"
				}
			});
			this.interval = chart.intervalStack()
				.position("count")
				.color("item")
				.tooltip("item*count", (item:string, count:number) => {
					return {
						name: item,
						value: count
					};
				});
			chart.on("click", (value:any) => {
				if(!value.data){
					// @ts-ignore
					return;
				}
				const data:any = value.data.point || value.data;
				if (data.deep === 1) {
					this.renderPie(data.id);
					this.activeFirst = data.id;
					this.activeSecond = 0;
				} else if (data.deep === 2) {
					this.activeSecond = data.id === this.activeSecond ? 0 : data.id;
				}
				this.renderLine();
			});
			chart.render();
			// @ts-ignore
			chart.hide();
			this.chart = chart;
			const lineChart = new G2.Chart({
				container: this.id2,
				forceFit: true,
				height: 300
			});
			lineChart.axis("time", {
				line: {
					stroke: "#FFF"
				},
				label: {
					textStyle: {
						fill: "#FFF"
					}
				}
			});
			lineChart.axis("value", {
				line: {
					stroke: "#FFF"
				},
				label: {
					textStyle: {
						fill: "#FFF"
					}
				}
			});
			lineChart.tooltip(true);
			lineChart.legend({
				textStyle: {
					fill: "#FFF"
				}
			});
			lineChart.area()
				.position("time*value")
				.color("type")
				.shape("smooth");
			lineChart.line()
				.position("time*value")
				.color("type")
				.shape("smooth")
				.size(2);
			lineChart.render();
			// @ts-ignore
			lineChart.hide();
			this.area = lineChart;
			request({
				url: "/energy/rest/category/"
			}).then(({ data }) => {
				this.system = (data.results as any[]).map(t => ({
					id: t.id,
					name: t.name,
					count: 0,
					deep: 1,
					children: [],
					change: 0
				}));
				this.system.pop();
				this.getEleCount();
			});
			request("/energy/rest/MnitorData/?EnergyCategory=5&type=day&pagesize=2&ordering=-id").then(({ data }) => {
				this.todayUsed = data.results[ 0 ].D_value;
			});
		}

		@Watch("$store.state.baseColor")
		onColorChange () {
			this.renderCss();
		}

		beforeRouteLeave (from:Route, to:Route, next:Function):void {
			this.MainLink.remove();
			next();
		}
	}

</script>
